import os

from aiogram import Bot, types
from aiogram_dialog import DialogManager, StartMode
from fluentogram import TranslatorRunner

from poker_bot.config import Settings
from poker_bot.core.constants import INVOICES_FOLDER
from poker_bot.core.models.enums.deposit import DepositStatus
from poker_bot.core.models.enums.user import UserRole
from poker_bot.core.utils.date_time import get_current_timestamp
from poker_bot.core.utils.files import get_file_extension
from poker_bot.database.services import (
    AccountService,
    DepositService,
    PaymentMethodService,
    UserService,
)
from poker_bot.tg_bot.keyboards.inline import deposit_payment_confirmation_kb
from poker_bot.tg_bot.services.tg_helpers import (
    answer_msg_with_autodelete,
    broadcast,
    delete_msg,
    send_tg_message,
)
from poker_bot.tg_bot.states import ClientSG


async def create_or_update_deposit(
    message: types.Message, __, manager: DialogManager, payment_amount: str
):
    bot: Bot = manager.middleware_data.get("bot")
    locale: TranslatorRunner = manager.middleware_data.get("locale")
    config: Settings = manager.middleware_data.get("config")
    deposit_service: DepositService = manager.middleware_data.get("deposit_service")
    user_service: UserService = manager.middleware_data.get("user_service")
    account_service: AccountService = manager.middleware_data.get("account_service")
    payment_method_service: PaymentMethodService = manager.middleware_data.get(
        "payment_method_service"
    )

    try:
        payment_amount = float(payment_amount)
    except ValueError:
        await answer_msg_with_autodelete(message, locale.get("wrong-sum-format-msg"))
        return

    payment_method_id: int = manager.dialog_data.get("payment_method_id")

    payment_method = await payment_method_service.get_payment_method_by_id(
        payment_method_id
    )

    if manager.start_data and manager.start_data.get("deposit_id"):
        deposit_id: int = manager.start_data.get("deposit_id")
    else:
        deposit_id: int = manager.dialog_data.get("deposit_id")

    # Обновляем валюту депозита, если он уже создан
    if deposit_id:
        await deposit_service.update_deposit_payment_method(
            deposit_id, payment_method_id
        )
    else:
        user = await user_service.get_user_by_telegram_id(message.from_user.id)
        deposit = await deposit_service.create_deposit(
            summ=float(payment_amount),
            user_tg_id=message.from_user.id,
            payment_method_id=payment_method_id,
            account_id=user.selected_account_id,
        )
        account = await account_service.get_account_by_id(user.selected_account_id)
        deposit_id = deposit.id
        await send_tg_message(
            bot,
            config.tg_bot.admin_channel_id,
            locale.get(
                "new-deposit-msg",
                deposit_id=deposit_id,
                username=user.username,
                account_id=str(account.account_id),
                deposit_summ=str(deposit.summ),
                currency_symbol=payment_method.currency_symbol.value,
                is_first_deposit="✅" if user.deposits_count == 0 else "❌",
                is_subscribed="✅" if user.is_subscribed else "❌",
            ),
        )

    manager.dialog_data["deposit_id"] = deposit_id
    deposit = await deposit_service.get_deposit_by_id(deposit_id)
    manager.dialog_data["deposit_summ"] = deposit.summ

    await manager.next()


async def process_invoice_screenshot(message: types.Message, _, manager: DialogManager):
    """Валидируем и сохраняем скриншот об оплате депозита"""

    bot: Bot = manager.middleware_data.get("bot")
    locale: TranslatorRunner = manager.middleware_data.get("locale")
    config: Settings = manager.middleware_data.get("config")
    deposit_service: DepositService = manager.middleware_data.get("deposit_service")
    user_service: UserService = manager.middleware_data.get("user_service")

    deposit_id: int = manager.dialog_data.get("deposit_id")

    if message.document:
        file = message.document
        extension = get_file_extension(file.file_name)
        if extension not in ["jpeg", "jpg", "png"]:
            await answer_msg_with_autodelete(
                message, locale.get("wrong-photo-extension")
            )
            return

    elif message.photo:
        file = message.photo[-1]

    file = await bot.get_file(file.file_id)
    msg = await message.answer(locale.get("photo-processing-msg"))

    filename = f"{message.from_user.id}_{get_current_timestamp()}.png"

    destination_path = os.path.join(INVOICES_FOLDER, filename)
    await bot.download_file(file.file_path, destination_path)

    await deposit_service.update_deposit_invoice_path(deposit_id, filename)
    await delete_msg(msg)

    await message.answer(locale.get("after-payment-msg"))

    # Отправляем сообщение для подтверждения оплаты админам магазина
    admins = await user_service.get_users_with_role(UserRole.admin)
    await broadcast(
        bot,
        admins,
        locale.get("new-deposit-for-payment-confirmation-msg", deposit_id=deposit_id),
        reply_markup=deposit_payment_confirmation_kb(locale, deposit_id=deposit_id),
    )

    await send_tg_message(
        bot,
        config.tg_bot.admin_channel_id,
        locale.get(
            "deposit-status-changed-msg",
            deposit_id=deposit_id,
            status=DepositStatus.waiting_payment.value,
        ),
    )

    await manager.start(ClientSG.start, mode=StartMode.RESET_STACK)
